package com.example.sendmessage.server.dao;

import com.example.sendmessage.SendMessageApplication;
import com.example.sendmessage.common.MqException;
import com.example.sendmessage.server.core.Binding;
import com.example.sendmessage.server.core.Exchange;
import com.example.sendmessage.server.core.ExchangeType;
import com.example.sendmessage.server.core.Queue;
import com.example.sendmessage.server.mapper.MetaMapper;

import java.io.File;
import java.util.List;

/**
 * 数据库管理类
 * 对交换机、队列、绑定接口统一封装管理
 */
public class DataBaseManager {
    private MetaMapper metaMapper;

    /**
     * 数据库管理初始化操作，不存在就创建，存在则不创建
     * @throws MqException 抛出目录创建的异常
     */
    public void init() throws MqException {
        // 获取MetaMapper
        metaMapper = SendMessageApplication.context.getBean(MetaMapper.class);
        if (!checkDBExists()) {
            // 不存在就创建相关目录及数据库
            // 创建目录
            createDir();
            // 创建数据库
            createDB();
            // 添加默认数据
            addDefaultData();
            System.out.println("[DataBaseManage] 创建相关数据库文件，初始化完成！");
        } else {
            System.out.println("[DataBaseManage] 相关数据库已经存在，初始化完成！");
        }
    }

    /**
     * 检查数据库是否存在
     * @return 数据库是否存在
     */
    private boolean checkDBExists() {
        File file = new File("./data/meta.db");
        return file.exists();
    }

    /**
     * 创建data目录
     * @throws MqException 抛出创建失败的异常
     */
    private void createDir() throws MqException {
        File dir = new File("./data");
        if (!dir.exists()) {
            boolean ok = dir.mkdirs();
            if (ok) {
                System.out.println("[DataBaseManage] data目录创建成功！");
            } else {
                throw new MqException("[DataBaseManage] data目录创建失败！");
            }
        }
    }

    /**
     * 创建数据库、数据表
     */
    private void createDB() {
        metaMapper.createExchangeTable();
        metaMapper.createQueueTable();
        metaMapper.createBindingTable();
        System.out.println("[DataBaseManage] 数据库创建成功！");
    }

    /**
     * 清空数据文件
     * @throws MqException data目录删除失败异常
     */
    public void deleteDB() throws MqException {
        // windows 系统只能先将文件删除才能删除目录
        File file = new File("./data/meta.db");
        boolean result = file.delete();
        if (result) {
            System.out.println("[DataBaseManage] 数据库文件删除成功！");
        } else {
            throw new MqException("[DataBaseManage] 数据库文件删除成功！");
        }
        File dir = new File("./data");
        result = dir.delete();
        if (result) {
            System.out.println("[DataBaseManage] data目录删除成功！");
        } else {
            throw new MqException("[DataBaseManage] data目录删除成功！");
        }
    }

    /**
     * 添加默认数据
     */
    private void addDefaultData() {
        Exchange exchange = new Exchange();
        exchange.setName("");
        exchange.setType(ExchangeType.DIRECT);
        exchange.setDurable(true);
        exchange.setAutoDelete(false);
        metaMapper.insertExchange(exchange);
        System.out.println("[DataBaseManage] 默认数据添加完成！");
    }

    /**
     * 新增一个交换机
     * @param exchange 交换机
     */
    public void insertExchange(Exchange exchange) {
        metaMapper.insertExchange(exchange);
    }

    /**
     * 删除交换机
     * @param exchangeName 删除的交换机名字
     */
    public void deleteExchange(String exchangeName) {
        metaMapper.deleteExchange(exchangeName);
    }

    /**
     * 查看所有的交换机
     * @return 数据库中所有的交换机
     */
    public List<Exchange> selectAllExchanges() {
        return metaMapper.selectAllExchanges();
    }

    /**
     * 新增一个队列
     * @param queue 新增的队列
     */
    public void insertQueue(Queue queue) {
        metaMapper.insertQueue(queue);
    }

    /**
     * 删除队列
     * @param queueName 删除队列的名字
     */
    public void deleteQueue(String queueName) {
        metaMapper.deleteQueue(queueName);
    }

    /**
     * 查询所有的队列
     * @return 数据库中所有的队列
     */
    public List<Queue> selectAllQueues() {
        return metaMapper.selectAllQueues();
    }

    /**
     * 添加绑定关系
     * @param binding 绑定关系
     */
    public void insertBinding(Binding binding) {
        metaMapper.insertBinding(binding);
    }

    /**
     * 删除绑定关系
     * @param binding 绑定关系
     */
    public void deleteBinding(Binding binding) {
        metaMapper.deleteBinding(binding);
    }

    /**
     * 查询所有的绑定的关系
     * @return 数据库中的绑定关系
     */
    public List<Binding> selectAllBindings(){
        return metaMapper.selectAllBindings();
    }
}
